/*
 * KrakencitoApp.java
 */
package krakencito;

import java.util.Hashtable;
import java.util.List;
import org.jdesktop.application.Application;
import org.jdesktop.application.SingleFrameApplication;

import java.net.*;
import java.io.*;
import java.util.*;
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import javax.xml.stream.XMLInputFactory;

/**
 * The main class of the application.
 */
public class KrakencitoApp extends SingleFrameApplication {

    public static Hashtable<String, List<String>> prohibidas;

    /**
     * At startup create and show the main frame of the application.
     */
    @Override
    protected void startup() {
        show(new KrakencitoView(this));
    }

    /**
     * This method is to initialize the specified window by injecting resources.
     * Windows shown in our application come fully initialized from the GUI
     * builder, so this additional configuration is not needed.
     */
    @Override
    protected void configureWindow(java.awt.Window root) {
    }

    /**
     * A convenient static getter for the application instance.
     * @return the instance of KrakencitoApp
     */
    public static KrakencitoApp getApplication() {
        return Application.getInstance(KrakencitoApp.class);
    }

    /**
     * Main method launching the application.
     */
    public static void main(String[] args) {

        KrakencitoApp.prohibidas = LeerProhibidas();

        Thread proxy_manager = new Thread(new ProxyManager(KrakencitoApp.prohibidas));
        proxy_manager.start();
        //ProgramaPrincipal();
        launch(KrakencitoApp.class, args);
    }

    /*
     * Función LeerProhibidas(): Se encarga de leer el archivo .xml con la
     * lista de páginas prohibidas y retorna una hashtable cuyas claves son el
     * ip del servidor y sus valores son sus respectivas listas de subdirectorios
     * prohibidos.
     */
    public static Hashtable<String, List<String>> LeerProhibidas() {
        Hashtable<String, List<String>> prohibidas = new Hashtable<String, List<String>>();

        XMLInputFactory inputFactory = XMLInputFactory.newInstance();

        try {
            InputStream input = new FileInputStream(new File("Recursos/prohibidas.xml"));
            XMLStreamReader xmlStreamReader = inputFactory.createXMLStreamReader(input);
            String servidor = "";
            List<String> Subdirectorios = new ArrayList<String>();
            String currentElement = "";
            while (xmlStreamReader.hasNext()) {
                int evento = xmlStreamReader.next();
                switch (evento) {
                    case XMLStreamReader.START_ELEMENT:
                        // Se toma el nombre del nuevo elemento (servidor, subdirectorio, etc)
                        currentElement = xmlStreamReader.getLocalName().trim();
                        break;
                    case XMLStreamReader.CHARACTERS:
                        if (currentElement.equals("direccion")) {
                            if (!xmlStreamReader.getText().trim().isEmpty()) {
                                /*
                                 * Si el elemento es una dirección, se obtiene el valor
                                 * de la misma y se busca su dirección IP. El substring
                                 * se hace dado que el getByName retorna un string con formato
                                 * hostname/ip.
                                 */
                                String serv = InetAddress.getByName(xmlStreamReader.getText().trim()).toString();
                                servidor = serv.substring(serv.indexOf("/") + 1);
                                Subdirectorios = new ArrayList<String>();
                            }
                        } else if (currentElement.equals("subdirectorio")) {
                            // Si es un subdirectorio se agrega a la lista para ese servidor
                            if (!xmlStreamReader.getText().trim().isEmpty()) {
                                String subdir = xmlStreamReader.getText().trim();
                                // Si el ultimo caracter del subdir no es un /, se coloca uno.
                                if (subdir.lastIndexOf("/") != (subdir.length() - 1)) {
                                    subdir += "/";
                                }
                                Subdirectorios.add(subdir);
                            }
                        }
                        break;
                    case XMLStreamReader.END_ELEMENT:
                        // Si el elemento que finaliza es un servidor, se agrega la informacion
                        // al hashtable.
                        if (xmlStreamReader.getLocalName().trim().equals("servidor")) {
                            prohibidas.put(servidor, Subdirectorios);
                        }
                        break;
                    default:
                        break;
                }
            }
        } catch (Exception e) {
            System.err.println("No se encuentra el archivo de páginas prohibidas");
        }
        return prohibidas;
    }

    public static void ArmarXML(Hashtable<String, List<String>> prohibidas) {
        XMLOutputFactory xof = XMLOutputFactory.newInstance();
        XMLStreamWriter xtw = null;
        try {
            xtw = xof.createXMLStreamWriter(new FileWriter("Recursos/prohibidas.xml"));
            xtw.writeStartDocument("1.0");
            xtw.writeStartElement("prohibidas");
            Enumeration keys = prohibidas.keys();
            while (keys.hasMoreElements()) {
                String key = keys.nextElement().toString();
                List<String> value = prohibidas.get(key);
                xtw.writeStartElement("servidor");
                xtw.writeStartElement("direccion");
                InetAddress address = InetAddress.getByName(key);
                String nombre_servidor = address.getHostName();
                xtw.writeCharacters(nombre_servidor);
                xtw.writeEndElement();
                for(int i = 0; i < value.size(); i++){
                    xtw.writeStartElement("subdirectorio");
                    xtw.writeCharacters(value.get(i));
                    xtw.writeEndElement();
                }
                xtw.writeEndElement();
            }
            xtw.writeEndElement();
            xtw.flush();
            xtw.close();
        } catch (Exception e) {
            System.err.println("No se encuentra el archivo de páginas prohibidas");
        }
    }
}
